/* Grupo 8:
Caio Augusto da Silva Gomes - 7239072
Francisco Angelo Cabelo - 7277652
Gabriela Ruch Salmeron - 7239350
*/

#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>     /* atoi */


#define sizeX 720 // Invertido
#define sizeY 1280

//Matrizes que vao guardar cada canal de cor
int imagemR[sizeX][sizeY]; //RED
int imagemG[sizeX][sizeY]; //GREEN
int imagemB[sizeX][sizeY]; //BLUE
//Matrizes que vao guardar a imagem com blur
int outimagemR[sizeX][sizeY]; //RED
int outimagemG[sizeX][sizeY]; //GREEN
int outimagemB[sizeX][sizeY]; //BLUE

int main()
{

    int i,j,cx,cy;
    time_t inicioTempo = time(NULL);
    time_t tempo;

    // memset()
    memset (imagemR,0,sizeof(int)*sizeX*sizeY);
    memset (imagemG,0,sizeof(int)*sizeX*sizeY);
    memset (imagemB,0,sizeof(int)*sizeX*sizeY);
    memset (outimagemR,0,sizeof(int)*sizeX*sizeY);
    memset (outimagemG,0,sizeof(int)*sizeX*sizeY);
    memset (outimagemB,0,sizeof(int)*sizeX*sizeY);

    char linha[1000];
    int valor; //Pega o valor da linha
    int countCor = 0; // 0->R  1->G  2->B
    int ri = 0; //Contadores individuais das matrizes de cor
    int rj = 0;
    int gi = 0;
    int gj = 0;
    int bi = 0;
    int bj = 0;

tempo = time(NULL) - inicioTempo;
printf("%ld : Abrindo arquivo e carregando na memoria...\n", tempo);

    // Abrir o arquivo
    FILE * file;
    file = fopen( "HD.ppm" , "r");

    //Pula as 4 primeiras linhas, que sao comentarios e informacoes da imagem
    for ( i = 0; i < 4; i ++){
        fgets(linha, 1000, file);
    }

    //Quebra a imagem ppm em 3 matrizes RED GREEN BLUE
    while ( fgets(linha, 10, file)  != NULL ) {

    //Converte string para inteiro
    valor = atoi(linha);

    //Verifica se chegou no no ultimo pixel de X e incrementa Y
    if(bi == sizeY){
        ri = 0;
        rj++;
        gi = 0;
        gj++;
        bi = 0;
        bj++;
        //printf("\n");
    }

        if(countCor == 0){ //Salva em RED
            imagemR[rj][ri] = valor;
            countCor = 1;
            ri++;
            continue;
        }
        if(countCor == 1){ //Salva em GREEN
            imagemG[gj][gi] = valor;
            countCor = 2;
            gi++;
            continue;
        }
        if(countCor == 2){ //Salva em BLUE
            imagemB[bj][bi] = valor;
            countCor = 0;
            bi++;
            continue;
        }

    }

    fclose(file);

tempo = time(NULL) - inicioTempo;
printf("%ld : Arquivo salvo na memoria.\n",tempo);
printf("Aplicando filtro de blur...\n");


    //Realiza o filtro blur em cada matriz

    //RED
    int media=0;
    int centro[2];//Pixel central do filtro
    //Posicao inicial para 5x5
    centro[0] = 2; // X
    centro[1] = 2; // Y

    for(i=0; i< sizeY-4; i++){
        for(j=0; j < sizeX-4; j++){

            //Calcula a media para o pixel do centro
            for (cx = centro[0]-2; cx <= centro[0] + 2; cx++){
                for (cy = centro[1]-2; cy <= centro[1] + 2; cy++){
                    media = media + imagemR[cx][cy];
                }
            }
            media = media/25;
            outimagemR[centro[0]][centro[1]] = media;
            centro[0]++;
        }
        centro[1]++;
        centro[0] = 2;
    }

    //GREEN
    media=0;
    //Posicao inicial para 5x5
    centro[0] = 2; // X
    centro[1] = 2; // Y

    for(i=0; i< sizeY-4; i++){
        for(j=0; j < sizeX-4; j++){

            //Calcula a media para o pixel do centro
            for (cx = centro[0]-2; cx <= centro[0] + 2; cx++){
                for (cy = centro[1]-2; cy <= centro[1] + 2; cy++){
                    media = media + imagemG[cx][cy];
                }
            }
            media = media/25;
            outimagemG[centro[0]][centro[1]] = media;
            centro[0]++;
        }
        centro[1]++;
        centro[0] = 2;
    }

    //BLUE
     media=0;
    //Posicao inicial para 5x5
    centro[0] = 2; // X
    centro[1] = 2; // Y

    for(i=0; i< sizeY-4; i++){
        for(j=0; j < sizeX-4; j++){

            //Calcula a media para o pixel do centro
            for (cx = centro[0]-2; cx <= centro[0] + 2; cx++){
                for (cy = centro[1]-2; cy <= centro[1] + 2; cy++){
                    media = media + imagemB[cx][cy];
                }
            }
            media = media/25;
            outimagemB[centro[0]][centro[1]] = media;
            centro[0]++;
        }
        centro[1]++;
        centro[0] = 2;
    }

tempo = time(NULL) - inicioTempo;
printf("%ld : Filtro Aplicado.\n",tempo);
printf("Salvando matrizes no arquivo...\n");

    //Salva de volta como arquivo ppm
    // Abrir o arquivo
    FILE * out;
    out = fopen( "out_8k.ppm" , "w+");
    char saida[1000];
    char aux[100];

    //Coloca as 4 primeiras linhas:
    fputs("P3\n",out);

    sprintf(saida,"%d %d\n",sizeY,sizeX);
    fputs(saida,out);

    sprintf(saida,"# Imagem dos Brother\n");
    fputs(saida,out);

    fputs("255\n",out);

    //Coloca as matrizes de cor na saida ppm
    countCor = 0;
    ri = 0;
    rj = 0;
    gi = 0;
    gj = 0;
    bi = 0;
    bj = 0;

    while ( rj < sizeX && ri < sizeX*3 ){

        if(bi == sizeY){
        ri = 0;
        rj++;
        gi = 0;
        gj++;
        bi = 0;
        bj++;
    }

        if(countCor == 0){ //Salva em RED
            sprintf(aux,"%d",outimagemR[rj][ri]);
            strcpy (saida,aux);
            strcat(saida,"\n");
            fputs(saida,out);
            countCor = 1;
            ri++;
            continue;
        }
        if(countCor == 1){ //Salva em GREEN
            sprintf(aux,"%d",outimagemG[gj][gi]);
            strcpy (saida,aux);
            strcat(saida,"\n");
            fputs(saida,out);
            countCor = 2;
            gi++;
            continue;
        }
        if(countCor == 2){ //Salva em BLUE
            sprintf(aux,"%d",outimagemB[bj][bi]);
            strcpy (saida,aux);
            strcat(saida,"\n");
            fputs(saida,out);
            countCor = 0;
            bi++;
            continue;
        }



    }

    fclose(out);
tempo = time(NULL) - inicioTempo;
printf("%ld : Arquivo salvo em out.ppm\n",tempo);

   return 0;
}
